#include "VisionCone.h"

using namespace ui;

//El angulo es determinado por el tanque del cliente
VisionCone::VisionCone(int posX, int posY,int angle) : SceneObject(posX,  posY, 290, 250, "") 
{
	setAngle(angle);
	setSpeed(0);
	setAngularSpd(0);
	setRotation(false);
	this->id =0;
	rotation =true;
}

VisionCone::~VisionCone(void)
{
	while(!this->rotSurfaces->empty()){ 
		SDL_FreeSurface( this->rotSurfaces->back()); 
		this->rotSurfaces->pop_back();
	};
	delete this->rotSurfaces;
	
	SDL_FreeSurface(second_background);
}

void VisionCone::setRotation(bool flag)
{
	this->rotation = flag;
}

bool VisionCone::getRotation(){
	return this->rotation;
}

void VisionCone::setSpeed(int speed)
{
	this->speed = speed;
}

int VisionCone::getSpeed(){
	return this->speed;
}

void VisionCone::setAngularSpd(int angSpd)
{
	this->angularSpd = angSpd;
}

int VisionCone::getAngularSpd(){
	return this->angularSpd;
}

void VisionCone::setSceneBackgroundPath(string path)
{
	sceneBackgroundPath = path;
}

void VisionCone::loadSurface() throw (SDL_Exception)
{
	string path_background = SCENEOBJECT_PATH;
	path_background.append("VisionCone.png");

	SDL_Surface *cone_surface = IMG_Load(path_background.c_str());
	setBackgroundSurf(SDL_DisplayFormatAlpha(cone_surface));
	SDL_FreeSurface(cone_surface);

	if( getBackgroundSurf() == NULL )
	{
	    std::string errorMessage ("SCENE OBJECT - LOAD SURFACE - ERROR");
	    throw(SDL_Exception(errorMessage));
	}
	
	this->rotSurfaces = new LISTSUR();
	SDL_Surface* s;
	for (int i = 0; i < 36; i++){
		s = rotozoomSurface (getBackgroundSurf(),i*10, 1, 0);
		this->rotSurfaces->push_back(s);
	}
	this->surfaces_it = this->rotSurfaces->begin();
	
	//Se carga el fondo del escenario para tapar aquellas zonas que no deben verse
	second_background = IMG_Load(sceneBackgroundPath.c_str());
	second_background = SDL_DisplayFormat( second_background);
	SDL_SetColorKey(second_background, SDL_SRCCOLORKEY, SDL_MapRGB( second_background->format, 255,242, 0));
		
	if( second_background == NULL )
	{
		std::string errorMessage ("SCENE OBJECT - LOAD SURFACE - ERROR");
		throw(SDL_Exception(errorMessage));
	}
	
	//Resize del segundo fondo
	if(second_background->w != 800 || second_background->h != 600)
	{
		try
		{
			SDL_Surface* resized_background = this->resize(800, 600, second_background);
			SDL_FreeSurface(second_background);
			second_background = SDL_DisplayFormat(resized_background);
			SDL_FreeSurface(resized_background);
		}
		catch (SDL_Exception)
		{
			std::string errorMessage ("VISIONCONE - RESIZE SURFACE - ERROR");
			throw(SDL_Exception(errorMessage));
		}
	}
	
}

void VisionCone::rotate(){
	
	this->angle += angularSpd;
	this->angle = angle % 360;
	
	
}


void VisionCone::move(Component* s)
{	
	int x = getXCoordinate();
	int y = getYCoordinate();

	int incx = (int)(getSpeed() * sinf((float)(getAngle() * M_PI / 180)));
	int incy = (int)(getSpeed() * cosf((float)(getAngle() * M_PI / 180)));

	y += incy;
	x += incx;

	setXCoordinate(x);
	setYCoordinate(y);

}

void VisionCone::draw(SDL_Surface* s)
{
	SDL_Surface *second_backgroundAUX  = SDL_DisplayFormat( second_background);
	SDL_SetColorKey(second_backgroundAUX, SDL_SRCCOLORKEY, SDL_MapRGB( second_background->format, 255,242, 0));

	if( this->angle < 0){
		int aux = (angle + 360)/10;
		this->surfaces_it = this->rotSurfaces->begin();
		for (int i = 0 ; i<aux ; i++ )
			surfaces_it++;			
	}else{
		if ( this->angle > 0){
			int aux = angle/10;
			this->surfaces_it = this->rotSurfaces->begin();
			for (int i = 0 ; i<aux ; i++ )
				surfaces_it++;			
		}
		else
			this->surfaces_it = this->rotSurfaces->begin();
	}
	
	//Es la superficie rotada que corresponde dibujar.
	this->rotated_surface = *this->surfaces_it;

	if(!getRotation())
	{
		SDL_Rect object_rect;

		object_rect.x = getXCoordinate() - getWidth() / 2;
		object_rect.y = getYCoordinate() - getHeight() / 2;
		object_rect.w = getWidth();
		object_rect.h = getHeight();

		//ajuste
		object_rect.x += (int)(70* sinf((float)(getAngle() * M_PI / 180)));
		object_rect.y += (int)(70* cosf((float)(getAngle() * M_PI / 180)));

		if(SDL_BlitSurface(getBackgroundSurf(), NULL, second_backgroundAUX, &object_rect))
		{
			std::string errorMessage("SCENE OBJECT - BLIT SURFACE - ERROR");
			throw SDL_Exception (errorMessage);
		}

		object_rect.x = 29; object_rect.y = 26;
		object_rect.w = 800; object_rect.h = 600;
		
		if(SDL_BlitSurface(second_backgroundAUX, NULL, s, &object_rect))
		{
			std::string errorMessage("SCENE OBJECT - BLIT SURFACE - ERROR");
			throw SDL_Exception (errorMessage);
		}

	}else{

		/*SDL_Rect pos={this->getXCoordinate(),this->getYCoordinate(), getWidth(), getHeight()};*/
		SDL_Rect pos={this->getXCoordinate(),this->getYCoordinate(), 0,0};
		pos.x -= rotated_surface->w/ 2;
		pos.y -= rotated_surface->h /2;
		pos.x -= 29;
		pos.y -= 26;
		//ajuste
		/*pos.x += (int)(70* sinf((float)(getAngle() * M_PI / 180)));
		pos.y += (int)(70* cosf((float)(getAngle() * M_PI / 180)));*/

		if(SDL_BlitSurface(rotated_surface, NULL, second_backgroundAUX, &pos))
		{
			std::string errorMessage("SCENE OBJECT - BLIT SURFACE - ERROR");
			throw SDL_Exception (errorMessage);
		}
		pos.x = 29; pos.y = 26;
		pos.w = 800; pos.h = 600;
		if(SDL_BlitSurface(second_backgroundAUX, NULL, s, &pos))
		{
			std::string errorMessage("SCENE OBJECT - BLIT SURFACE - ERROR");
			throw SDL_Exception (errorMessage);
		}

		//rotation=false;
	}

	SDL_FreeSurface(second_backgroundAUX);
}

SDL_Surface* VisionCone::resize(float newWidth, float newHeigth, SDL_Surface* screen){
	SDL_Surface* newscreen=NULL;

    float width_image=(float)(screen->w);
    float heigth_image=(float)(screen->h);

    float zoomX = (newWidth/width_image);
    float zoomY = (newHeigth/heigth_image);

	return newscreen = rotozoomSurfaceXY(screen,0,zoomX,zoomY,0);
}

